package jonaVisual;
import java.awt.*;

import Jona.*;

public class Arrow implements VisualObject{
	private Point[] p1;
	private Polygon poly1;
	Head h1;
	private int arrow_length = 10;
	private Conditional c1;
	private int polyBounds = 5;
	private boolean drawPoly = false;
	private int lineWidth = 1;

	public void translatefirst(int x,int y)
	{
		if(p1 != null)
		{
			p1[0].translate(x,y);
		}	
	}
	
	public Rectangle getBounds() {return poly1.getBounds();}
	public ArgObject getArgObject() {return c1;}
	public Arrow(Conditional c1)
	{	
		this.c1 = c1;
	}
	
	public void doHighlight() { lineWidth =2;}
	public void deHighLight() { lineWidth =1;}

	public void translate(int x,int y)
	{
		if(poly1 != null)
			poly1.translate(x,y);
		if(p1 != null)
		{
			for(int i = 0; i < p1.length ; i++)
			{
				p1[i].translate(x,y);
			}
		}
	}	
	
	public boolean isHighlighted()
	{
		return(lineWidth==2);
	}
	
	public void clicked()
	{
		if(lineWidth== 1)lineWidth = 2;
		else lineWidth = 1;
	}
	
	public void addPoint(int x, int y)
	{
		if(p1 == null)
		{
			p1 = new Point[1];
			p1[0] = new Point(x,y);
		}
		else
		{
			Point[] dum = new Point[p1.length+1];
			for(int i =0;i < p1.length;i++)
				dum[i] = p1[i];
			dum[p1.length] = new Point(x,y);
			p1 = dum;
		}
		setArrow();
		//addPolygon();
	}
	
	private void makePolygon()
	{
		poly1 = new Polygon();
		float dx,dy;
		double angle;
		Point[] dum = new Point[p1.length -1];		
		Point[] dum2 = new Point[p1.length -1];
		
		for(int i= 0; i < (p1.length -1); i++)
		{
			dx = p1[i + 1].x  - p1[i].x;
			dy = p1[i + 1].y  - p1[i].y;	
			if(dx != 0.0f)
			{
				angle = Math.atan(dy/dx);
				//System.out.println(angle);
				if(dx > 0)
				{
					angle += Math.PI;
				}				
			}
			else
			{
				if(dy > 0)
				{
					angle = -Math.PI / 2;
				}
				else
				{
					angle = Math.PI/2;
				}
			}
			poly1.addPoint((int)(p1[i].x + (polyBounds * Math.cos(angle + (Math.PI/2)))),(int)(p1[i].y +(polyBounds * Math.sin(angle + (Math.PI/2)))));
			poly1.addPoint((int)(p1[i + 1].x + (polyBounds * Math.cos(angle + (Math.PI/2)))),(int)(p1[i +1].y +(polyBounds * Math.sin(angle + (Math.PI/2)))));
			dum[i] = new Point((int)(p1[i].x + (polyBounds * Math.cos(angle - (Math.PI/2)))),(int)(p1[i].y +(polyBounds * Math.sin(angle - (Math.PI/2)))));
			dum2[i] = new Point((int)(p1[i + 1].x + (polyBounds * Math.cos(angle - (Math.PI/2)))),(int)(p1[i +1].y +(polyBounds * Math.sin(angle - (Math.PI/2)))));
		}
		for(int i = 0; i < (p1.length -1); i++)
		{
			poly1.addPoint(dum2[(p1.length-2) - i].x,dum2[(p1.length-2)-i].y);
			poly1.addPoint(dum[(p1.length-2) - i].x,dum[(p1.length-2)-i].y);						
		}
	}
	
	private void setArrow()
	{
		if(p1.length  > 1)
		{
			double angle;
			float dx = p1[p1.length-2].x  - p1[p1.length -1].x;
			float dy = p1[p1.length-2].y  - p1[p1.length -1].y;
			//System.out.println(dy + " " + dx);
			if(dx != 0.0f)
			{
				angle = Math.atan(dy/dx);
				//System.out.println(angle);
				if(dx > 0)
				{
					angle += Math.PI;
				}				
			}
			else
			{
				if(dy > 0)
				{
					angle = -Math.PI / 2;
				}
				else
				{
					angle = Math.PI/2;
				}
			}
		
			int x1= (int)(-arrow_length * Math.cos(angle + (Math.PI/4)));
			int y1=  (int)(-arrow_length * Math.sin(angle + (Math.PI/4)));
			Point p2 = new Point(x1,y1);
			x1=  (int)(-arrow_length * Math.cos(angle - (Math.PI/4)));
			y1=  (int)(-arrow_length * Math.sin(angle - (Math.PI/4)));
			Point p3 = new Point(x1,y1);
			
			h1 = new Head(p2,p3);
		}
	}
	
	//public boolean contains(int x, int y)
	//{
		//return contains(new Point(x,y));
	//}
	
	public boolean contains(int x,int y)
	{
		if(poly1 == null) makePolygon();
		return poly1.contains(x,y);
	}
	
	
	private void drawAll(Graphics2D g2, boolean negate)
	{
		g2.setColor(Color.black);
		//g2.draw(p1);
		//System.out.println("drawing");
		if(p1 != null)
		{
			if(p1.length > 1)
			{
				for(int i=0; i <(p1.length-1);i++)
				g2.drawLine(p1[i].x,p1[i].y,p1[i+1].x,p1[i+1].y);
				//g2.setColor(Color.red);
				//g2.drawLine(p1[p1.length-2].x,p1[p1.length-2].y,p1[p1.length-1].x,p1[p1.length-1].y);
			}
			h1.draw(g2,new Point(p1[p1.length -1].x,p1[p1.length-1].y),negate);	
			
			if(poly1 != null && drawPoly)
			{	
				g2.setColor(Color.red);
				g2.draw(poly1);
			}
		}
	}

	public void draw(Graphics2D g2, Theory t1)
	{		

		if(c1 != null && h1 != null)
		{
			boolean negate = false;
			if(c1.getConsequent().getClass().getSimpleName().equals("Negation"))
			{
				negate = true;
			}

			if(c1.getArgumentType() == Statement.ISSUE)
			{
				float[] dashPattern = { 2,3,2,3};
		
				g2.setStroke(new BasicStroke(lineWidth, BasicStroke.CAP_BUTT,
	                                  		BasicStroke.JOIN_MITER, 10,
	                                  		dashPattern, 0));	
				g2.setColor(Color.black);
				if(p1 != null)
				{
					if(p1.length > 1)
					{
						for(int i=0; i <(p1.length-1);i++)
							g2.drawLine(p1[i].x,p1[i].y,p1[i+1].x,p1[i+1].y);
							//g2.setColor(Color.red);
							//g2.drawLine(p1[p1.length-2].x,p1[p1.length-2].y,p1[p1.length-1].x,p1[p1.length-1].y);
					}
					//float[] dashPattern2 = {3,1,3,1};
					//g2.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
	               //   		BasicStroke.JOIN_MITER, 10,
	               //   		dashPattern2, 0));	
					g2.setStroke(new BasicStroke(lineWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER , 10,null,0));
					if(poly1 != null && drawPoly)
					{	
						g2.setColor(Color.red);
						g2.draw(poly1);
					}
					h1.draw(g2,new Point(p1[p1.length -1].x,p1[p1.length-1].y),negate);	
				}
			}
			else
			{
				g2.setStroke(new BasicStroke(lineWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER , 10,null,0));
				drawAll(g2,negate);
			}		
		}
	}
}

class Head
{
	private Point p1;
	private Point p2;
	
	public Head(Point p1,Point p2)
	{
		this.p1 = p1;
		this.p2 = p2;
	}
		
	public void draw(Graphics2D g2, Point sp1, boolean negative)
	{
		g2.drawLine(sp1.x,sp1.y,p1.x + sp1.x,p1.y + sp1.y);
		g2.drawLine(sp1.x,sp1.y,p2.x + sp1.x,p2.y + sp1.y);		
		if(negative)
		{
			g2.drawLine(sp1.x,sp1.y,-p1.x + sp1.x,-p1.y + sp1.y);
			g2.drawLine(sp1.x,sp1.y,-p2.x + sp1.x,-p2.y + sp1.y);		
		}
	}
	
}
